home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / sound / speech recognition sample / language.c next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  7.8 KB  |  286 lines

  1. /*
  2.     File:        Language.c
  3.  
  4.     Contains:    
  5.  
  6.     Written by:     
  7.  
  8.     Copyright:    Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.                 8/2/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  20.                 
  21.  
  22. */
  23. #ifndef __LANGUAGE__
  24. #include "Language.h"
  25. #endif
  26. #include <Errors.h>
  27.  
  28. OSErr        MakeNewLanguage        (SpeechInfoPtr theSpeechInfo)
  29. {
  30.     OSErr        theErr        = noErr;
  31.  
  32.     /* Make language models */
  33.     theErr = ReadInLanguages (theSpeechInfo);
  34.  
  35.     /* Use this LM in recognition */
  36.     if (theErr == noErr) {
  37.         theErr = SRSetLanguageModel (theSpeechInfo->theRecognizer, theSpeechInfo->languages->theLanguage);
  38.     }
  39.  
  40.     return theErr;
  41. }
  42.  
  43. OSErr    ReadInLanguages            (SpeechInfoPtr theSpeechInfo)
  44. {
  45.     LanguageModelListPtr    currentLang            = nil;
  46.     TREEResourcePtr            TREEResPtr            = nil;
  47.     short                    numLanguages        = 0,
  48.                             onlySubPath            = false,
  49.                             i;
  50.     OSErr                    theErr                = noErr;
  51.  
  52.     numLanguages = Count1Resources (kTREEType);
  53.     theErr = ResError ();
  54.  
  55.     theSpeechInfo->languages = (LanguageModelListPtr)NewPtr (sizeof (LanguageModelList));
  56.     theSpeechInfo->languages->nextLanguage = nil;
  57.     currentLang = theSpeechInfo->languages;
  58.  
  59.     for (i = 0; i < numLanguages; i++) {
  60.         theErr = GetTREERes (&TREEResPtr, kBaseResID + i, 1, &onlySubPath);
  61.         DisposePtr ((Ptr)TREEResPtr);
  62.         if (onlySubPath == false) {
  63.             theErr = AddStringsToLanguage (theSpeechInfo, currentLang, kBaseResID + i);
  64.             if (i+1 < numLanguages) {
  65.                 currentLang->nextLanguage = (LanguageModelListPtr)NewPtr (sizeof (LanguageModelList));
  66.                 currentLang = currentLang->nextLanguage;
  67.             }
  68.             else {
  69.                 currentLang->nextLanguage = nil;
  70.             }
  71.             currentLang->resID = kBaseResID + i;
  72.         }
  73.     }
  74.  
  75.     return theErr;
  76. }
  77.  
  78. OSErr    AddStringsToLanguage        (SpeechInfoPtr theSpeechInfo, LanguageModelListPtr currentLang, short resID)
  79. {
  80.     SRLanguageModel            newModel;
  81.     SRPath                    beginningOfPath,
  82.                             restOfPath;
  83.     Str63                    phraseString;
  84.     OSType                    type                = 0;
  85.     TREEResourcePtr            TREEResPtr            = nil;
  86.     CommandPtr                theCommand            = nil;
  87.     long                    refCon                = 0,
  88.                             flags                = 0,
  89.                             ID                    = 0;
  90.     short                    j                    = 1,
  91.                             onlySubPath            = false;
  92.     OSErr                    theErr                = noErr;
  93.     Boolean                    done                = false;
  94.  
  95.     theErr = SRNewLanguageModel (theSpeechInfo->recogSystem, &newModel, nil, 0);
  96.     refCon = resID;
  97.     theErr = SRSetProperty (newModel, kSRRefCon, &refCon, sizeof (refCon));
  98.     /* add each phrase to LM */
  99.     refCon = refCon << 16;
  100.     do {
  101.         theErr = GetTREERes (&TREEResPtr, resID, j, &onlySubPath);
  102.         if (theErr == noErr) {
  103.             theErr = GetFlagsFromTREE (&flags, TREEResPtr);
  104.         }
  105.         if (theErr == noErr && flags == 0) {
  106.             /* Read resource to get top level names to be recognized */
  107.             theErr = GetStringFromTREE (phraseString, TREEResPtr);
  108.             if (phraseString[0] == 0) {
  109.                 theErr = noErr;
  110.                 done = true;    /* Found the last name */
  111.             }
  112.             if (done == false) {
  113.                 theErr = RegisterCommand (TREEResPtr, &theCommand);
  114.                 theErr = SRAddText (newModel, phraseString+1, phraseString[0], (long)theCommand);
  115.             }
  116.         }
  117.         else if (theErr == noErr && flags == 1) {
  118.         /*    This word is the beginning of a path, i.e. "lights X" where X can
  119.             be on, off, dim, etc. */
  120.             theErr = GetTypeFromTREE (&type, TREEResPtr);
  121.             if (theErr == noErr && type == kTREEType) {
  122.                 theErr = GetIDFromTREE (&ID, TREEResPtr);
  123.             }
  124.             if (theErr == noErr) {
  125.                 theErr = SRNewPath (theSpeechInfo->recogSystem, &beginningOfPath);
  126.                 if (theErr == noErr) {
  127.                     theErr = GetStringFromTREE (phraseString, TREEResPtr);
  128.                     if (phraseString[0] == 0) {
  129.                         theErr = noErr;
  130.                         done = true;    /* Found the last name */
  131.                     }
  132.                     if (done == false) {
  133.                         theErr = SRAddText (beginningOfPath, phraseString+1, phraseString[0], 0);
  134.                         if (theErr == noErr) {
  135.                             theErr = GetTREERes (&TREEResPtr, ID, 1, &onlySubPath);
  136.                         }
  137.                         if (theErr == noErr) {
  138.                             theErr = AddStringsToLanguage (theSpeechInfo, currentLang, ID);
  139.                         }
  140.                         if (theErr == noErr) {
  141.                             theErr = SRNewPath (theSpeechInfo->recogSystem, &restOfPath);
  142.                             if (theErr == noErr) {
  143.                                 theErr = SRAddLanguageObject (restOfPath, currentLang->theLanguage);
  144.                             }
  145.                             if (theErr == noErr) {
  146.                                 theErr = SRAddLanguageObject (beginningOfPath, restOfPath);
  147.                             }
  148.                             if (theErr == noErr) {
  149.                                 theErr = SRAddLanguageObject (newModel, beginningOfPath);
  150.                             }
  151.                         }
  152.                     }
  153.                 }
  154.             }
  155.         }
  156.         j++;
  157.     } while (theErr == noErr && done == false);
  158.     if (theErr == resNotFound) {
  159.         theErr = noErr;
  160.     }
  161.     if (theErr != noErr) {    /*    release newly created LM if an error occured while adding phrases */
  162.         SRReleaseObject (newModel);
  163.     }
  164.     else {                    /*    return new LM */
  165.     //We don't release the language models because we will be switching between them later
  166.         currentLang->theLanguage = newModel;
  167.     }
  168.  
  169.     return theErr;
  170. }
  171.  
  172. OSErr    GetTREERes                (TREEResourcePtr *theTREEResPtr, short resID, short index, short *onlySubPath)
  173. {
  174.     TREEResourcePtr        TREEResPtr        = nil;
  175.     Handle                TREEHandle        = nil;
  176.     long                offset            = 0;
  177.     OSErr                theErr            = noErr;
  178.     short                itemCount        = 0,
  179.                         i;
  180.  
  181.     TREEHandle = Get1Resource (kTREEType, resID);
  182.     theErr = ResError ();
  183.     if (TREEHandle != nil && theErr == noErr) {
  184.         *onlySubPath = ((short *)*TREEHandle)[0];
  185.         itemCount = ((short *)*TREEHandle)[1];
  186.         if (index > itemCount || index < 1) {
  187.             theErr = resNotFound;
  188.         }
  189.         else {
  190.             offset = 4;        /* account for one time bytes at start of resource */
  191.             for (i = 0; i < index; i++) {
  192.                 TREEResPtr = (TREEResourcePtr)&(*TREEHandle)[offset];
  193.                 offset += 12;    /* account for flags, type, and ID */
  194.                 /* length of string (plus size byte), rounded to a quad byte length */
  195.                 offset += (((TREEResPtr->name[0] + 1) + 3) & ~3);
  196.             }
  197.             *theTREEResPtr = (TREEResourcePtr)NewPtr (sizeof (TREEResource) + TREEResPtr->name[0]);
  198.             if (*theTREEResPtr != nil && MemError () == noErr) {
  199.                 (*theTREEResPtr)->flags    = TREEResPtr->flags;
  200.                 (*theTREEResPtr)->type    = TREEResPtr->type;
  201.                 (*theTREEResPtr)->ID    = TREEResPtr->ID;
  202.                 for (i = 0; i < TREEResPtr->name[0] + 1; i++) {
  203.                     (*theTREEResPtr)->name[i] = TREEResPtr->name[i];
  204.                 }
  205.             }
  206.             ReleaseResource (TREEHandle);
  207.             theErr = ResError ();
  208.         }
  209.     }
  210.  
  211.     return theErr;
  212. }
  213.  
  214. OSErr    RegisterCommand            (TREEResourcePtr theTREEResPtr, CommandPtr *theCommand)
  215. {
  216.     OSErr                theErr            = noErr;
  217.  
  218.     *theCommand = (CommandPtr)NewPtr (sizeof(Command));
  219.  
  220.     theErr = GetFlagsFromTREE (&(*theCommand)->flags, theTREEResPtr);
  221.     theErr = GetTypeFromTREE (&(*theCommand)->type, theTREEResPtr);
  222.     theErr = GetIDFromTREE (&(*theCommand)->ID, theTREEResPtr);
  223.  
  224.     return theErr;
  225. }
  226.  
  227. OSErr    GetFlagsFromTREE        (long *theFlags, TREEResourcePtr theTREEResPtr)
  228. {
  229.     OSErr                theErr            = noErr;
  230.  
  231.     if (theTREEResPtr != nil) {
  232.         *theFlags = theTREEResPtr->flags;
  233.     }
  234.     else {
  235.         theErr = kNilPtrErr;
  236.     }
  237.  
  238.     return theErr;
  239. }
  240.  
  241. OSErr    GetTypeFromTREE            (OSType *theType, TREEResourcePtr theTREEResPtr)
  242. {
  243.     OSErr                theErr            = noErr;
  244.  
  245.     if (theTREEResPtr != nil) {
  246.         *theType = theTREEResPtr->type;
  247.     }
  248.     else {
  249.         theErr = kNilPtrErr;
  250.     }
  251.  
  252.     return theErr;
  253. }
  254.  
  255. OSErr    GetIDFromTREE            (long *theID, TREEResourcePtr theTREEResPtr)
  256. {
  257.     OSErr                theErr            = noErr;
  258.  
  259.     if (theTREEResPtr != nil) {
  260.         *theID = theTREEResPtr->ID;
  261.     }
  262.     else {
  263.         theErr = kNilPtrErr;
  264.     }
  265.  
  266.     return theErr;
  267. }
  268.  
  269. OSErr    GetStringFromTREE        (Str255 theString, TREEResourcePtr theTREEResPtr)
  270. {
  271.     OSErr                theErr            = noErr;
  272.     short                i;
  273.  
  274.     if (theTREEResPtr != nil) {
  275.         for (i = 0; i < theTREEResPtr->name[0] + 1; i++) {
  276.             theString[i] = theTREEResPtr->name[i];
  277.         }
  278.     }
  279.     else {
  280.         theString[0] = 0;
  281.         theErr = kNilPtrErr;
  282.     }
  283.  
  284.     return theErr;
  285. }
  286.